<?php

/**
 * This file is part of the Codizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Codizer Core Team <team@codizer.org>
 * @package     Codizer
 */

class f_file_File
{
    private static $instances;

	protected $file;
	protected $basename;
	protected $dirname;
	protected $extension;
	protected $filename;
	
	/**
	 * @param string $file
	 */
	private function __construct($file)
	{
		if(file_exists(realpath($file)))
		{
			$this->file = realpath($file);
		}
		else
		{
			if(strstr($file, 'http://'))
			{
				// @todo check url
				$this->file = $file;
			}			
		}

		$this->getFileProperties($file);

		return $this;
	}

	/**
	 * @param string $file
	 * @return f_file_File
	 */
	public static function getInstance($file)
	{
        if(!isset(self::$instances[$file]))
        {
            self::$instances[$file] = new self($file);
        }
		return self::$instances[$file];
	}

	/**
	 * Get file properties
	 *
	 * @param string $file
	 * @return array<String>
	 */
	protected function getFileProperties($file)
	{
		$infos = array();

		$infos = pathinfo($file);

		$infos['dirname'] = realpath($infos['dirname']);

		foreach ($infos as $key => $info)
		{
			$this->$key = $info;
		}

	}
	
	/**
	 * Get filesize in octets
	 *
	 * @return integer
	 */
	public function getFileSize()
	{
		return filesize($this->file);
	}

	/**
	 * Format filesize to human readable size
	 *
	 * @param integer $filesize
	 * @return string
	 */
	public function getFilesizeFormatted($lang = null)
	{
        $bytes = $this->getFileSize();

        switch($lang)
        {
            case 'fr' : $symbols = array('o', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'Yo'); break;
            default : $symbols = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); break;
        }
        $exp = $bytes ? floor(log($bytes) / log(1024)) : 0;

        return sprintf('%.2f '.$symbols[$exp], ($bytes/pow(1024, floor($exp))));
	}
	
	/**
	 * Get the creation date
	 *
	 * @return string
	 */
	public function getCreationDate()
	{
		return $this->formatDate(filectime($this->file));
	}
	
	/**
	 * Get the creation date
	 *
	 * @return string
	 */
	public function getModificationDate()
	{
		return $this->formatDate(filemtime($this->file));
	}	

	/**
	 * Format a date to the framework lang
	 *
	 * @param integer $timeStamp
	 * @return string
	 */
	private function formatDate($timeStamp, $smartFormat = null)
	{
		$date = f_date_Date::getInstance(date("Y-m-d H:i:s", $timeStamp));
		if(is_null($smartFormat))
		{
			$date = f_date_DateFormat::formatByLang($date, f_core_Context::getInstance()->getLang());			
		}
		else
		{
			$date = f_date_DateFormat::smartFormatByLang($date, $smartFormat, f_core_Context::getInstance()->getLang());
		}
		return $date;
	}
	
	/**
	 * Get file creation date formatted by smart format
	 *
	 * @param string $smartFormat
	 * @return string
	 */
	public function getCreationSmartDate($smartFormat)
	{
		return $this->formatDate(filectime($this->file), $smartFormat);
	}
	
	/**
	 * Get file modification date formatted by smart format
	 *
	 * @param string $smartFormat
	 * @return string
	 */
	public function getModificationSmartDate($smartFormat)
	{
		return $this->formatDate(filemtime($this->file), $smartFormat);
	}

	/**
	 * Get the mime type from an xml file
	 *
	 * @return string
	 */
	public function getMimeType()
	{
		if(function_exists('finfo_file'))
		{
    	     $finfo = finfo_open(FILEINFO_MIME);
    	     $mime = finfo_file($finfo, $this->file);
    	     finfo_close($finfo);
    	     return $mime;  
	  	}

        $mime = f_xml_Xpath::getInstance(FRAMEWORK_HOME.DS.'file'.DS.'mimetype'.DS.'mimes.xml')->fromXpath('extension[@id="'.strtolower($this->extension).'"]/mimetype')->getElement();

        if(!is_null($mime))
        {
            return $mime->getContent();
        }
		
		return "";
	}
	
	/**
	 * Is current file an image or not
	 *
	 * @return boolean
	 */
	public function isImage()
	{
		if($this->getMimeType() != "")
		{
			list($mainType, $mimeType) = explode("/", $this->getMimeType());
			return (strtolower($mainType) == "image");
		}
		return false;
	}
	
	/**
	 * Return image dimension if image
	 *
	 * @return array
	 */
	public function getDimensions()
	{
		if($this->isImage())
		{
			return getimagesize($this->file);
		}
		return null;
	}

	/**
	 * Force download the file
	 */
	public function forceDownload($renameFile = NULL)
	{
		$filename = $this->basename;

        if(is_null($renameFile))
        {
            $renameFile = $fileName;
        }

		header('Content-Type: application/force-download; name="'.$filename.'"');
		header("Content-Length: ".$this->filesize);
		header("Content-Disposition: attachment; filename=\"".$renameFile."\"");

		readfile($this->file);
	}
	
	///////////////////////////// GENERIC /////////////////////////
	
	/**
	 * Return the file with path
	 * ex : /home/web/www/index.php
	 *
	 * @return string
	 */
	public function getFile()
	{
		return $this->file;
	}
	
	/**
	 * Return the basename
	 * ex : index
	 *
	 * @return string
	 */
	public function getBaseName()
	{
		return $this->basename;
	}	
	
	/**
	 * Return the filename
	 * ex : index.php
	 *
	 * @return string
	 */
	public function getFileName()
	{
		return $this->filename;
	}
	
	/**
	 * Return the extension
	 * ex : php
	 *
	 * @return string
	 */
	public function getExtension()
	{
		return $this->extension;
	}
	
	/**
	 * Return the dirname
	 * ex: /home/web/www
	 *
	 * @return string
	 */
	public function getDir()
	{
		return $this->dirname;
	}	
}